package org.tru42.signal.processors.io.usb.usbprog;

import org.tru42.signal.lang.NamedBitSet;
import org.tru42.signal.lang.SObject;
import org.tru42.signal.lang.annotation.Sink;

import ch.ntb.usb.Device;
import ch.ntb.usb.LibusbJava;
import ch.ntb.usb.USB;
import ch.ntb.usb.USBException;

public class SimplePort extends SObject {

	protected final int USB_TIMEOUT = 1000;
	
	protected final int IN_EP_ADDR = 2;
	protected final int OUT_EP_ADDR = 3;
	
	protected final byte CMD_PORT_DIR = 1;
	protected final byte CMD_PORT_SET = 2;
	
	private Device usbDevice;
	
	public SimplePort() {
		super();
		try {
			LibusbJava.usb_init();
			usbDevice = USB.getDevice((short)0x1781, (short)0x0c62);
			usbDevice.updateDescriptors();
			if(usbDevice.getConfigDescriptors() != null)
				usbDevice.open(usbDevice.getConfigDescriptors()[0].getBConfigurationValue(), 0, 0);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Sink
	public void input(long timestamp, NamedBitSet value) {
		try {
			usbDevice.writeBulk(OUT_EP_ADDR, value.toByteArray(), 2, USB_TIMEOUT, false);
		} catch (USBException e) {
			e.printStackTrace();
		}
	}
	
	@Sink
	public void direction(long timestamp, NamedBitSet value) {
		try {
			usbDevice.writeBulk(OUT_EP_ADDR, value.toByteArray(), 2, USB_TIMEOUT, false);
		} catch (USBException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void dispose() {
		if(usbDevice != null)
			try {
				usbDevice.close();
			} catch (USBException e) {
				e.printStackTrace();
			}
		super.dispose();
	}
}
